// 通用配置

import type { App } from "vue";
import type { AppConfig } from "./type";
import axios from "axios";
import { joinUrls } from "@/utils/truncate";

const { pkg } = __APP_INFO__;
const { VITE_ASYNC_CONFIG_URL, VITE_USE_MOCK } = import.meta.env;

/**
 * 系统配置
 * 只读
 */
const appConfig: AppConfig = {
  runMode: "online",
  isMockMode: VITE_USE_MOCK.toString() === "true",
  request: {
    whiteList: ["/access/refresh-token", "/access/login"],
    url: reqConfig => {
      reqConfig.url = reqConfig.url || "";
      // 获取基底api地址，支持从env直接获取
      let baseAPI = import.meta.env.VITE_BASE_API;
      if (reqConfig.baseAPI) {
        const envKey = `VITE_${reqConfig.baseAPI}_API`.toUpperCase();
        if (import.meta.env[envKey]) {
          baseAPI = import.meta.env[envKey];
        } else {
          baseAPI = "/";
          window.console.warn(`unknown env api '${envKey}'`);
        }
        // 返回实际服务器地址
        return joinUrls(baseAPI, reqConfig.url);
      }
      // 如果请求地址中包含http头，直接返回
      if (/^(https?:\/\/|\/\/)/.test(reqConfig.url)) {
        return reqConfig.url;
      }
      // 是否已开启mock
      if (appConfig.isMockMode) {
        // 返回mock地址（即原地址）
        return reqConfig.url;
      }
      // 返回实际服务器地址
      return joinUrls(baseAPI, reqConfig.url);
    },
    response: (res: any): HttpResponse => {
      if (res) {
        if (!res.data?.success) {
          throw new Error(res.data?.message || "请求未响应，请稍候重试");
        } else {
          return { message: res.data?.message, data: res.data?.data };
        }
      } else {
        return { message: "请求异常，请稍候重试", data: null };
      }
    },
    pollingInterval: 60
  },
  router: {
    whiteList: ["/login"],
    localOnly: false,
    localIgnore: ["System", "Template"],
    routeMenuKey: "routeName"
  }
};

/**
 * 站点配置
 * 可硬编码，也可通过配置 .env => VITE_ASYNC_CONFIG_URL 动态覆写
 */
let siteConfig: PlatformConfigs = {
  // 平台版本号
  Version: pkg.version,
  // 平台标题
  Title: pkg.name,
  // 是否固定页头和标签页（true 内容区超出出现纵向滚动条 false 页头、标签页、内容区可纵向滚动）
  FixedHeader: true,
  // 隐藏菜单和页头，只显示标签页和内容区
  HiddenSideBar: false,
  // 是否开启持久化标签
  MultiTagsCache: true,
  // 是否开启组件缓存（此处不同于路由的 keepAlive，如果此处为 true 表示设置路由的 keepAlive 起效，反之设置 false 屏蔽平台整体的 keepAlive，即使路由设置了keepAlive 也不再起作用）
  KeepAlive: true,
  // 导航菜单模式 （vertical 左侧菜单模式、horizontal 顶部菜单模式、mix 混合菜单模式）
  Layout: "vertical",
  // 主题模式，可在src/style/theme.scss中配置
  Theme: "light",
  // 是否默认开启暗黑模式（动态修改无效）
  DarkMode: false,
  // 整体风格（浅色：light、深色：dark、自动：system）
  OverallStyle: "light",
  // 灰色模式
  Grey: false,
  // 色弱模式
  Weak: false,
  // 是否隐藏标签页
  HideTabs: false,
  // 是否隐藏页脚
  HideFooter: true,
  // 是否固定页宽（支持自定义宽度）
  Stretch: false,
  // vertical左侧菜单模式模式下侧边栏状态（true 展开、false 收起）
  SidebarStatus: true,
  // 主题色
  EpThemeColor: "#1989fa",
  // 是否显示logo
  ShowLogo: window.platform !== "win32",
  // 标签页风格（smart 灵动模式、card 卡片模式）
  ShowModel: "smart",
  // 菜单展开、收起图标是否开启动画，如遇菜单展开、收起卡顿设置成 true 即可（默认 false，开启动画）
  MenuArrowIconNoTransition: false,
  // 是否开启动态路由缓存本地的全局配置，默认 false
  CachingAsyncRoutes: false,
  // 可配置平台主体所有 el-tooltip 的 effect 属性，默认 light，不会影响业务代码
  TooltipEffect: "light",
  // 本地响应式存储的命名空间
  ResponsiveStorageNameSpace: "responsive-"
};

/**
 * 读取指定配置
 *
 * @param key 键名（支持.操作符）
 * @returns
 */
export const getConfig = (key?: string): PlatformConfigs => {
  if (typeof key === "string") {
    const arr = key.split(".");
    if (arr && arr.length) {
      let data = siteConfig;
      arr.forEach(v => {
        if (data && typeof data[v] !== "undefined") {
          data = data[v];
        } else {
          data = null;
        }
      });
      return data;
    }
  }
  return siteConfig;
};

/**
 * 获取项目动态全局配置
 *
 * @param app APP
 * @returns
 */
export const getPlatformConfig = async (app: App): Promise<PlatformConfigs> => {
  app.config.globalProperties.$config = getConfig();
  const url = VITE_ASYNC_CONFIG_URL;
  if (url) {
    // 开启
    return axios({
      method: "get",
      url
    })
      .then(({ data: config }) => {
        let $config = app.config.globalProperties.$config;
        // 自动注入系统配置
        if (app && $config && typeof config === "object") {
          $config = Object.assign($config, config);
          app.config.globalProperties.$config = $config;
          // 设置全局配置
          siteConfig = Object.assign(siteConfig, $config);
        }
        return $config;
      })
      .catch(() => {
        // 保证读取失败时程序可正常运行
        window.console.warn("配置文件“" + url + "”读取失败！本次忽略");
        return getConfig();
      });
  } else {
    // 不开启
    return getConfig();
  }
};

/**
 * 本地响应式存储的命名空间
 *
 * @returns
 */
export const responsiveStorageNameSpace = () =>
  getConfig().ResponsiveStorageNameSpace;

export default appConfig;
